home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / memory / xms100pc / xmmlib.cpp < prev    next >
C/C++ Source or Header  |  1994-09-29  |  16KB  |  642 lines

  1. //===========================================================================
  2. //
  3. //  XMMLIB.CPP -- XMM API routines, Copyright 1994, Paul Chang
  4. //
  5. //---------------------------------------------------------------------------
  6. //
  7. //  Credit:
  8. //
  9. //    This code was developed based on the XMS version 2.0 specification,
  10. //    copyright (c) 1988, Microsoft Corporation, Lotus Development
  11. //    Corporation, Intel Corporation, and AST Research, Inc.
  12. //
  13. //---------------------------------------------------------------------------
  14. //
  15. //  Legal speak:
  16. //
  17. //    This code is public domain and free, and may be distributed free of any
  18. //    charge or royalty, in the spirit of free software.
  19. //
  20. //    All code, including source, object, and executable, may be used, free
  21. //    of any charge and royalty, provided that the developer gives credit
  22. //    to the original author should any of said code be used in either
  23. //    public domain or commercial software products.
  24. //
  25. //    The developer may use this code with the understanding that the
  26. //    original author is in no way held responsible for any damage that may
  27. //    arise from usage of any of said code.
  28. //
  29. //    Usage of said code includes incorporation into larger programs,
  30. //    possible alteration of original code, and redistribution.
  31. //
  32. //---------------------------------------------------------------------------
  33. //
  34. //  Translation:
  35. //
  36. //    You can give this code away for free because this code is free.
  37. //
  38. //    You can use this code for free, but if you decide to build something
  39. //    useful with it, give me some credit, will you?
  40. //
  41. //    If you use this code and it somehow screws you or your system over,
  42. //    I'm not responsible, because I told you so.  Besides, I'm too poor
  43. //    to be sued.
  44. //
  45. //    You can compile stuff with this code, you can even change this code,
  46. //    and you can redistribute it, as long as you play nice and give me
  47. //    some credit.
  48. //
  49. //---------------------------------------------------------------------------
  50. //
  51. //  Why is this freeware?
  52. //
  53. //    Because I doubt that anything I write could be commercially successful.
  54. //    Besides, I have a job that feeds me, so I don't really need your
  55. //    money.
  56. //
  57. //  Why do I include source code?
  58. //
  59. //    Because I know how frustrating it is to link a library without having
  60. //    the ability to look at the source code.
  61. //
  62. //  Why do I give you permission to alter code?
  63. //
  64. //    Because I know how frustrating it is to link a library without having
  65. //    the ability to alter the source code.
  66. //
  67. //  Why do I want you to give me some credit?
  68. //
  69. //    Because I've spent some time on this code, and I'd like to be
  70. //    recognized for that effort if you choose to use it.
  71. //
  72. //  Why is this written in C++?
  73. //
  74. //    Because I hate C.  Besides, double-slash comments are nice.  If you
  75. //    don't like it, tough -- try writing your OWN XMM library then.
  76. //
  77. //===========================================================================
  78.  
  79. #ifndef _XMMLIB_CPP
  80. #define _XMMLIB_CPP
  81.  
  82. #include "xmmlib.h"
  83.  
  84. //===========================================================================
  85. //
  86. //  Global Variables
  87. //
  88. //===========================================================================
  89.  
  90. const char XMMLIB_Version[] = "XMMLIB Version 1.0 Beta";  //  XMMLIB version
  91.  
  92. //  XMM_GetControl() finds the 32-bit address of the XMM control function
  93. //    and places it here
  94.  
  95. dword XMM_Control = 0;        //  Stores address of XMM control function
  96.  
  97. //  XMM_GetVersion() finds the 16-bit BCD version of the XMM and places it
  98. //    in XMM_Version and, in string form, in XMM_VerString
  99.  
  100. word XMM_Version = 0;        //  16-bit BCD of XMM version
  101. char XMM_VerString[] = "00.00";    //  String contains XMM version
  102.  
  103. //  Believe it or not, XMM_GetVersion() finds out if the HMA is available and
  104. //    reports it with this global variable
  105.  
  106. word XMM_HMA = 0;        //  Contains 1 if HMA is available
  107.  
  108. //  I was going to declare this as a far pointer to something allocated from
  109. //    the heap, but when I load DS:SI with the address of XMM_MoveStruct, I
  110. //    can't make a "call [XMM_Control]" because XMM_Control is in the data
  111. //    segment, while things in the heap are often in a different segment.  In
  112. //    other words, XMM_MoveStruct and XMM_Control should be in the same
  113. //    segment, or else bad things will happen (program crash).
  114.  
  115. XMM_Move XMM_MoveStruct;    //  Contains move information
  116.  
  117. //===========================================================================
  118. //
  119. //  Function Declarations
  120. //
  121. //===========================================================================
  122.  
  123. //---------------------------------------------------------------------------
  124. //
  125. //  XMM_Installed()
  126. //
  127. //    Returns 1 if an XMM exists, 0 otherwise
  128. //
  129. //---------------------------------------------------------------------------
  130.  
  131. byte XMM_Installed()
  132. {
  133.     byte RetVal;
  134.  
  135.     asm {
  136.     mov    ax, XMM_INSTALL            // Test for XMM
  137.     int    XMM_CALL
  138.     mov    RetVal, al
  139.     }
  140.  
  141.     if (RetVal == XMM_INSTALLED) {
  142.     return(TRUE);
  143.     } else {
  144.     return(FALSE);
  145.     }
  146. }
  147.  
  148. //---------------------------------------------------------------------------
  149. //
  150. //  XMM_GetControl()
  151. //
  152. //    Returns address of XMM control function
  153. //
  154. //    XMM_Control contains XMM control function 32-bit address
  155. //
  156. //---------------------------------------------------------------------------
  157.  
  158. dword XMM_GetControl()
  159. {
  160.     asm {
  161.     push    es
  162.     mov    ax, XMM_CONTROL            //  Get Control Function
  163.     int    XMM_CALL
  164.     mov    word ptr [XMM_Control], bx    //  Standard Intel LE
  165.     mov    word ptr [XMM_Control+2], es    //    Segment:Offset notation
  166.     pop    es
  167.     }
  168.  
  169.     return(XMM_Control);
  170. }
  171.  
  172. //---------------------------------------------------------------------------
  173. //
  174. //  XMM_GetVersion()
  175. //
  176. //    Returns 16-bit BCD of XMM version, or 0 if XMM_Control is 0
  177. //
  178. //    XMM_Version contains 16-bit BCD of XMM version
  179. //    XMM_HMA contains 1 if HMA exists, 0 otherwise
  180. //
  181. //---------------------------------------------------------------------------
  182.  
  183. word XMM_GetVersion()
  184. {
  185.     if (XMM_Control == 0) {
  186.     return(0);
  187.     }
  188.  
  189.     asm {
  190.     mov    ah, XMM_GET_VERSION
  191.     call    [XMM_Control]
  192.     mov    XMM_HMA, dx
  193.     mov    XMM_Version, bx
  194.     }
  195.  
  196.     return(XMM_Version);
  197. }
  198.  
  199. //---------------------------------------------------------------------------
  200. //
  201. //  XMM_GetVerHigh()
  202. //  XMM_GetVerLow()
  203. //  XMM_GetVerString()
  204. //
  205. //    XMM_GetVerHigh() returns the whole part of the XMM version number
  206. //    XMM_GetVerLow() returns the fractional part of the XMM version number
  207. //    XMM_GetVerString() updates XMM_VerString with the XMM version number,
  208. //    and returns that string
  209. //
  210. //    All three functions call upon XMM_GetVersion() if it XMM_Version is 0
  211. //
  212. //---------------------------------------------------------------------------
  213.  
  214. int XMM_GetVerHigh()
  215. {
  216.     if (XMM_Version == 0) {
  217.     XMM_GetVersion();
  218.     }
  219.  
  220.     return(((XMM_Version >> 12) & 0x0f) * 10 + ((XMM_Version >> 8) & 0x0f));
  221. }
  222.  
  223. int XMM_GetVerLow()
  224. {
  225.     if (XMM_Version == 0) {
  226.     XMM_GetVersion();
  227.     }
  228.  
  229.     return(((XMM_Version >> 4) & 0x0f) * 10 + (XMM_Version & 0x0f));
  230. }
  231.  
  232. char* XMM_GetVerString()
  233. {
  234.     int index;
  235.  
  236.     if (XMM_Version == 0) {
  237.     XMM_GetVersion();
  238.     }
  239.  
  240.     index = 0;
  241.     XMM_VerString[index] = ((XMM_Version >> 12) & 0x0f) + '0';
  242.     if (XMM_VerString[index] != '0') {
  243.     index ++;
  244.     }
  245.     XMM_VerString[index ++] = ((XMM_Version >> 8) & 0x0f) + '0';
  246.     XMM_VerString[index ++] = '.';
  247.     XMM_VerString[index ++] = ((XMM_Version >> 4) & 0x0f) + '0';
  248.     XMM_VerString[index ++] = (XMM_Version & 0x0f) + '0';
  249.     XMM_VerString[index] = 0;
  250.  
  251.     return(XMM_VerString);
  252. }
  253.  
  254. //---------------------------------------------------------------------------
  255. //
  256. //  XMM_Initialize()
  257. //
  258. //    Calls upon XMM_Installed(), XMM_GetControl(), and XMM_GetVersion()
  259. //
  260. //    Returns XMM_Control if successful, 0 othersize
  261. //
  262. //    It is highly suggested that XMM_Initialize() be called before anything
  263. //    else.  If you don't, your system WILL crash.
  264. //
  265. //---------------------------------------------------------------------------
  266.  
  267. dword XMM_Initialize()
  268. {
  269.     if (XMM_Installed() == 0) {
  270.     return(0);
  271.     }
  272.  
  273.     if (XMM_GetControl() == 0 || XMM_GetVersion() == 0) {
  274.     return(0);
  275.     }
  276.  
  277.     return(XMM_Control);
  278. }
  279.  
  280. //---------------------------------------------------------------------------
  281. //
  282. //  XMM_QueryTotalFree()
  283. //
  284. //    Returns total XMS memory available in kilobytes
  285. //
  286. //---------------------------------------------------------------------------
  287.  
  288. word XMM_QueryTotalFree()
  289. {
  290.     word TotalFree;
  291.  
  292.     asm {
  293.     mov    ah, XMM_QUERY_FREE
  294.     call    [XMM_Control]
  295.     mov    TotalFree, dx
  296.     }
  297.  
  298.     return(TotalFree);
  299. }
  300.  
  301. //---------------------------------------------------------------------------
  302. //
  303. //  XMM_QueryTotalFree()
  304. //
  305. //    Returns largest extended memory block (EMB) available in kilobytes
  306. //
  307. //---------------------------------------------------------------------------
  308.  
  309. word XMM_QueryLargestFree()
  310. {
  311.     word LargestFree;
  312.  
  313.     asm {
  314.     mov    ah, XMM_QUERY_FREE
  315.     call    [XMM_Control]
  316.     mov    LargestFree, ax
  317.     }
  318.  
  319.     return(LargestFree);
  320. }
  321.  
  322. //---------------------------------------------------------------------------
  323. //
  324. //  XMM_AllocateBlock(size)
  325. //
  326. //    Allocates EMB in size kilobytes and returns the handle to the EMB
  327. //
  328. //---------------------------------------------------------------------------
  329.  
  330. word XMM_AllocateBlock(word size)
  331. {
  332.     word handle;
  333.  
  334.     asm {
  335.     mov    dx, size
  336.     mov    ah, XMM_ALLOCATE_BLOCK
  337.     call    [XMM_Control]
  338.     mov    handle, dx
  339.     }
  340.  
  341.     return(handle);
  342. }
  343.  
  344. //---------------------------------------------------------------------------
  345. //
  346. //  XMM_FreeBlock(handle)
  347. //
  348. //    Frees EMB of particular handle
  349. //
  350. //    Returns 0 upon success, errorcode otherwise
  351. //
  352. //---------------------------------------------------------------------------
  353.  
  354. byte XMM_FreeBlock(word handle)
  355. {
  356.     word RetVal;
  357.     byte ErrorCode;
  358.  
  359.     asm {
  360.     mov    dx, handle
  361.     mov    ah, XMM_FREE_BLOCK
  362.     call    [XMM_Control]
  363.     mov    RetVal, ax
  364.     mov    ErrorCode, bl
  365.     }
  366.  
  367.     if (RetVal == 0) {
  368.     return(ErrorCode);
  369.     } else {
  370.     return(0);
  371.     }
  372. }
  373.  
  374. //---------------------------------------------------------------------------
  375. //
  376. //  XMM_MoveMemory(length, srchnd, srcoff, dsthnd, dstoff)
  377. //
  378. //    Move memory to and from an EMB
  379. //
  380. //    Returns 1 upon success, 0 otherwise
  381. //
  382. //    XMM_MoveStruct is updated to hold move information
  383. //    XMM_Move structure is defined in xmmlib.h
  384. //
  385. //    Note:  You need not lock a block first before moving memory
  386. //
  387. //---------------------------------------------------------------------------
  388.  
  389. word XMM_MoveMemory(dword length,
  390.             word srchnd, dword srcoff,
  391.             word dsthnd, dword dstoff)
  392. {
  393.     word MoveStructOff = FP_OFF(&XMM_MoveStruct);
  394.     word RetVal;
  395.  
  396.     XMM_MoveStruct.Length = length;
  397.     XMM_MoveStruct.SourceHandle = srchnd;
  398.     XMM_MoveStruct.SourceOffset = srcoff;
  399.     XMM_MoveStruct.DestHandle = dsthnd;
  400.     XMM_MoveStruct.DestOffset = dstoff;
  401.  
  402.     asm {
  403.     mov    si, MoveStructOff
  404.     mov    ah, XMM_MOVE_MEMORY
  405.     call    [XMM_Control]
  406.     mov    RetVal, ax
  407.     }
  408.  
  409.     return(RetVal);
  410. }
  411.  
  412. //---------------------------------------------------------------------------
  413. //
  414. //  XMM_LockBlock(handle)
  415. //
  416. //    Locks a particular EMB
  417. //
  418. //    Returns DWORD containing 32-bit physical address of block, 0 if failure
  419. //
  420. //    Note:  You don't need to lock a block to call upon XMM_MoveMemory()
  421. //
  422. //---------------------------------------------------------------------------
  423.  
  424. dword XMM_LockBlock(word handle)
  425. {
  426.     word EMBSeg;
  427.     word EMBOff;
  428.     word RetVal;
  429.  
  430.     asm {
  431.     mov    dx, handle
  432.     mov    ah, XMM_LOCK_BLOCK
  433.     call    [XMM_Control]
  434.     mov    RetVal, ax
  435.     mov    EMBSeg, dx
  436.     mov    EMBOff, bx
  437.     }
  438.  
  439.     if (RetVal == 0) {
  440.     return(0);
  441.     }
  442.  
  443.     return(((dword) EMBSeg << 16) + EMBOff);
  444. }
  445.  
  446. //---------------------------------------------------------------------------
  447. //
  448. //  XMM_UnlockBlock(handle)
  449. //
  450. //    Unlocks a particular EMB
  451. //
  452. //    Returns 1 upon success, 0 otherwise
  453. //
  454. //---------------------------------------------------------------------------
  455.  
  456. word XMM_UnlockBlock(word handle)
  457. {
  458.     word RetVal;
  459.  
  460.     asm {
  461.     mov    dx, handle
  462.     mov    ah, XMM_UNLOCK_BLOCK
  463.     call    [XMM_Control]
  464.     mov    RetVal, ax
  465.     }
  466.  
  467.     return(RetVal);
  468. }
  469.  
  470. //---------------------------------------------------------------------------
  471. //
  472. //  XMM_LockCount(handle)
  473. //
  474. //    Returns the number of locks on a particular EMB, -1 upon failure
  475. //
  476. //---------------------------------------------------------------------------
  477.  
  478. int XMM_LockCount(word handle)
  479. {
  480.     word RetVal;
  481.     byte LockCount;
  482.  
  483.     asm {
  484.     mov    dx, handle
  485.     mov    ah, XMM_GET_HANDLE_INFO
  486.     call    [XMM_Control]
  487.     mov    RetVal, ax
  488.     mov    LockCount, bh
  489.     }
  490.  
  491.     if (RetVal == 0) {
  492.     return(-1);
  493.     }
  494.  
  495.     return((int) LockCount);
  496. }
  497.  
  498. //---------------------------------------------------------------------------
  499. //
  500. //  XMM_NumHandles(handle)
  501. //
  502. //    Returns the number of handles left for EMBs, -1 upon failure
  503. //
  504. //    Don't ask me why you need to pass a handle to obtain the number of free
  505. //    handles
  506. //
  507. //---------------------------------------------------------------------------
  508.  
  509. int XMM_NumHandles(word handle)
  510. {
  511.     word RetVal;
  512.     byte NumHandles;
  513.  
  514.     asm {
  515.     mov    dx, handle
  516.     mov    ah, XMM_GET_HANDLE_INFO
  517.     call    [XMM_Control]
  518.     mov    RetVal, ax
  519.     mov    NumHandles, bl
  520.     }
  521.  
  522.     if (RetVal == 0) {
  523.     return(-1);
  524.     }
  525.  
  526.     return((int) NumHandles);
  527. }
  528.  
  529. //---------------------------------------------------------------------------
  530. //
  531. //  XMM_BlockSize(handle)
  532. //
  533. //    Returns the length of a perticular block, 0 upon failure
  534. //
  535. //    Don't ask me why you need to pass a handle to obtain the number of free
  536. //    handles
  537. //
  538. //---------------------------------------------------------------------------
  539.  
  540. word XMM_BlockSize(word handle)
  541. {
  542.     word RetVal;
  543.     word BlockLength;
  544.  
  545.     asm {
  546.     mov    dx, handle
  547.     mov    ah, XMM_GET_HANDLE_INFO
  548.     call    [XMM_Control]
  549.     mov    RetVal, ax
  550.     mov    BlockLength, dx
  551.     }
  552.  
  553.     if (RetVal == 0) {
  554.     return(0);
  555.     }
  556.  
  557.     return(BlockLength);
  558. }
  559.  
  560. //---------------------------------------------------------------------------
  561. //
  562. //  XMM_ReallocateBlock(handle, length)
  563. //
  564. //    Tries to reallocate block to size length (in kilobytes)
  565. //
  566. //    Returns 1 upon success, 0 otherwise
  567. //
  568. //    If length is smaller than original size, data will be truncated
  569. //    Block must be unlocked before reallocation
  570. //
  571. //---------------------------------------------------------------------------
  572.  
  573. word XMM_ReallocateBlock(word handle, word length)
  574. {
  575.     word RetVal;
  576.  
  577.     asm {
  578.     mov    dx, handle
  579.     mov    bx, length
  580.     mov    ah, XMM_REALLOC_BLOCK
  581.     call    [XMM_Control]
  582.     mov    RetVal, ax
  583.     }
  584.  
  585.     return(RetVal);
  586. }
  587.  
  588. //---------------------------------------------------------------------------
  589. //
  590. //  XMM_memcpy(<destination>, <source>, n)
  591. //
  592. //    Calls upon XMM_MoveMemory()
  593. //
  594. //    These four overloaded functions provide the API to copy data between
  595. //    conventional memory and EMBs.  If the data location is in the EMB,
  596. //    a handle and offset are necessary;  otherwise, just a far pointer
  597. //    is sufficient for conventional memory.
  598. //
  599. //    Returns 1 upon success, 0 otherwise
  600. //
  601. //---------------------------------------------------------------------------
  602.  
  603. word XMM_memcpy(word dsthnd, dword dstoff,
  604.         word srchnd, dword srcoff,
  605.         dword n)
  606. {
  607.     return(XMM_MoveMemory(n, srchnd, srcoff, dsthnd, dstoff));
  608. }
  609.  
  610. word XMM_memcpy(word dsthnd, dword dstoff,
  611.         byte far* source,
  612.         dword n)
  613. {
  614.     word srchnd = 0;
  615.     dword srcoff = MK_DWORD(source);
  616.  
  617.     return(XMM_MoveMemory(n, srchnd, srcoff, dsthnd, dstoff));
  618. }
  619.  
  620. word XMM_memcpy(byte far* dest,
  621.         word srchnd, dword srcoff,
  622.         dword n)
  623. {
  624.     word dsthnd = 0;
  625.     dword dstoff = MK_DWORD(dest);
  626.  
  627.     return(XMM_MoveMemory(n, srchnd, srcoff, dsthnd, dstoff));
  628. }
  629.  
  630. word XMM_memcpy(byte far* dest, byte far* source, dword n)
  631. {
  632.     word srchnd = 0;
  633.     dword srcoff = MK_DWORD(source);
  634.     word dsthnd = 0;
  635.     dword dstoff = MK_DWORD(dest);
  636.  
  637.     return(XMM_MoveMemory(n, srchnd, srcoff, dsthnd, dstoff));
  638. }
  639.  
  640. #endif _XMMLIB_CPP
  641.  
  642.